using System.Buffers;
using SuperSocket.ProtoBase;

namespace SuperSocketProxy;

/*
+----+----------+----------+
|VER | NMETHODS | METHODS  |
+----+----------+----------+
| 1  |    1     | 1 to 255 |
+----+----------+----------+
+-------+----------+------------+
| VER   | NMETHODS |   METHODS  |
+-------+----------+------------+
| 0x05  |  0x02    | 0x00, 0x02 |
+-------+----------+------------+
 */
internal sealed class Socket5HandshakePipeFilter : FixedSizePipelineFilter<SocketProxyPacket>
{
    public Socket5HandshakePipeFilter() 
        : base(4)
    {
        NextFilter = new Socket5PipeFilter(SocketPipeFilterType.Handshake);
    }

    protected override SocketProxyPacket DecodePackage(ref ReadOnlySequence<byte> buffer)
    {
        var reader = new SequenceReader<byte>(buffer);
        
        return new Socket5HandshakePacket().Decode(ref reader);
    }
}

/*
    +----+------+----------+------+----------+
    |VER | ULEN |  UNAME   | PLEN |  PASSWD  |
    +----+------+----------+------+----------+
    | 1  |  1   | 1 to 255 |  1   | 1 to 255 |
    +----+------+----------+------+----------+
    这里的VER为子协议（用户口令认证协议）的版本。

    VER的值为0x01
    ULEN表示用户名UNAME的长度，大小为1个字节
    UNAME为用户名，长度范围为1-255个字节，长度由ULEN指定
    PLEN表示口令的长度，大小为一个字节
    PASSWD为口令，长度范围为1-255，长度由PLEN指定
 */

internal sealed class Socket5PipeFilter : PipelineFilterBase<SocketProxyPacket>
{
    private readonly SocketPipeFilterType _pipeFilter;
    
    private static readonly PacketFactoryPool PacketFactoryPool = new();
    
    static Socket5PipeFilter()
    {
        PacketFactoryPool.RegisterPacketType<Socket5AuthPassPacket>(SocketPipeFilterType.AuthUserName);
        PacketFactoryPool.RegisterPacketType<Socket5EndPointPacket>(SocketPipeFilterType.AuthEndPoint);
        PacketFactoryPool.RegisterPacketType<SocketProxyDataPacket>(SocketPipeFilterType.ForwardData);
    }
    
    public Socket5PipeFilter(SocketPipeFilterType nexFilterType)
    {
        _pipeFilter = nexFilterType;
    }
    
    public override SocketProxyPacket Filter(ref SequenceReader<byte> reader)
    {
        switch (_pipeFilter)
        {
            case SocketPipeFilterType.Handshake://当前握手完毕设置下一个过滤器为验证密码
                NextFilter = new Socket5PipeFilter(SocketPipeFilterType.AuthUserName);
                return default;
            case SocketPipeFilterType.AuthUserName://当前验证密码完毕设置下一个过滤器为验证地址
                NextFilter = new Socket5PipeFilter(SocketPipeFilterType.AuthEndPoint);
                break;
            case SocketPipeFilterType.AuthEndPoint://当前验证地址完毕设置下一个过滤器为转发数据
                NextFilter = new Socket5PipeFilter(SocketPipeFilterType.ForwardData);
                break;
            default:
                break;;
        }

        var packet = PacketFactoryPool.Create(_pipeFilter);
        
        return packet.Decode(ref reader);
    }
}